class LcInterface
{
public:

	LcInterface();
	void input( int argc, char * const argv[]);

	LcClassifier*  getClassifier(){ return my_classifier;}

	LcVideoReadExt getTrainVideo();
	LcVideoReadExt getTestVideo();


	bool IF_TRAIN;
	bool IF_TEST;

	int train_f_start;
	int train_f_end;
	int train_f_rate;

	int test_f_start;
	int test_f_end;
	int test_f_rate;

	int t_win;

	string root;

	string train_video_name;
	string test_video_name;

	string feature_code_string;

	string classifier_name;
	
	string ext;

	string addition_string;

	void buildDatasetmap();

	map< string , Vec3i> data_map;

	bool setVideo( string name ,int & start, int & end , int & rate);
	void setClassifier();

	void init();
	

	LcClassifier* my_classifier;

	float lambda;  // weight for link on space MRF

	float nu; //weight for time between

	float weight_heat_map; // weight for heat map , only for prototype,
	// require to fixed next refactor version

	float eta;

	int frame_filter_rate;

	double learning_rate;
	double cooling_rate;
	int iter_times;

	bool SAVE_IMG;	

	bool SAVE_LIKELI;

	bool FIX_LAMBDA;
	bool FIX_NU;
	bool FIX_HEAT;
	bool FIX_ETA;
};

LcVideoReadExt LcInterface::getTrainVideo()
{
	LcVideoReadExt ans;
	ans.video_name = train_video_name;
	ans.f_start = train_f_start;
	ans.f_end = train_f_end;
	ans.f_rate = train_f_rate;
	ans.t_win = t_win;
	ans.ext = ext;
	ans.root = root;
	return ans;
}

LcVideoReadExt LcInterface::getTestVideo()
{
	LcVideoReadExt ans;
	ans.video_name = test_video_name;
	ans.f_start = test_f_start;
	ans.f_end = test_f_end;
	ans.f_rate = test_f_rate;
	ans.t_win = t_win;
	ans.ext = ext;
	ans.root = root;
	return ans;
}

void LcInterface::setClassifier()
{
	if(classifier_name == "rdt")
	{
		my_classifier = new LcRandomTrees;
	}
}
void LcInterface::init()
{
	if(IF_TEST == false)
	{
		cout << " into " << endl;
		if(train_f_start<0) train_f_start = test_f_start;
		if(train_f_end<0) train_f_end = test_f_end;
		if(train_f_rate<0) train_f_rate = test_f_rate;
	}

	if(feature_code_string == "") feature_code_string = "l";

	if(classifier_name == "" ) classifier_name = "rdt";
	setClassifier();

	if(train_video_name == "" ){train_video_name = "GOPR2382_cab";}
	setVideo( train_video_name, train_f_start, train_f_end, train_f_rate);

	if(test_video_name == "" ){test_video_name = "GOPR2384_cab";}
	setVideo( test_video_name, test_f_start, test_f_end, test_f_rate);
}

LcInterface::LcInterface()
{
	train_f_start = -1;
	train_f_rate = -1;
	train_f_end = -1;

	test_f_start = -1;
	test_f_rate = -1;
	test_f_end = -1;

	t_win = 0;

	root = "./../_FGS/";
	train_video_name = "";
	test_video_name = "";
	feature_code_string = "";
	classifier_name = "";
	
	ext = ".avi";

	addition_string = "";


	frame_filter_rate = 1;

	IF_TEST = false;
	IF_TRAIN = false;

	buildDatasetmap();

	lambda = 0.0f;
	nu = 0.0f;
	weight_heat_map = 0.0f;

	eta = 0.00f;

	learning_rate = 0.1;
	cooling_rate = 0.5;
	iter_times = 30;

	SAVE_IMG = false;

	SAVE_LIKELI = false;

	FIX_LAMBDA = false;
	FIX_NU = false;
	FIX_HEAT = false;
	FIX_ETA = false;	
}

void LcInterface::buildDatasetmap()
{
	data_map.clear();
	data_map.insert( pair< string, Vec3i>( "GOPR2382_cab", Vec3i(150,5300,50)) );
	data_map.insert( pair< string, Vec3i>( "GOPR2384_cab", Vec3i(150,11200,25)) );
}

bool LcInterface::setVideo( string name ,int & start, int & end , int & rate)
{
	map<string , Vec3i>::iterator iter = data_map.find( name );
	if( iter != data_map.end())
	{
		Vec3i temp = iter->second;
		if(start<0)start = temp[0];
		if(end<0)end = temp[1];
		if(rate<0)rate = temp[2];
		return true;
	}
	else
	{
		cout << "One of Video is not in default" << endl;
		return false;
	}
}

void LcInterface::input( int argc, char * const argv[])
{
	for(int ind = 1;ind < argc;ind++)
	{
		/*** Parse switches ***/
		if (argv[ind][0] == '-') {
			switch (argv[ind][1]) {
				case 'f':
					root = string(argv[++ind]);
					break;
				case 't':
					train_video_name = string(argv[++ind]);
					break;
				case 'p':
					test_video_name = string(argv[++ind]);
					break;
				case 'v':
					feature_code_string =  string(argv[++ind]);
					break;
				case 'a':
					IF_TRAIN = true;
					break;
				case 'b':
					IF_TEST = true;
					break;
				case 's':
					//only for predict video setting , for trainning video it's always solid with frame
					// unless it's no testing model then the test frame setting will be use
					// as training parameter
					test_f_start =  atoi(argv[++ind]);
					break;
				case 'e':
					test_f_end = atoi(argv[++ind]);
					break;
				case 'y':
					ext = string(argv[++ind);
					break;
				case 'r':
					test_f_rate = atoi(argv[++ind]);
					break;
				case 'c':
					classifier_name = string(argv[++ind]);
					break;

				case 'w':
					t_win = atoi(argv[++ind]);
					break;

				case 'I':
					FIX_LAMBDA = true;
					break;
				case 'i':
					lambda = float( atof(argv[++ind]) );
					break;

				case 'J':
					FIX_NU = true;
					break;
				case 'j':
					nu =  float( atof(argv[++ind]) );
					break;

				case 'K':
					FIX_HEAT = true;
					break;
				case 'k':
					weight_heat_map = float( atof(argv[++ind]) );
					break;

				case 'O':
					FIX_ETA = true;
					break;
				case 'o':
					eta = atof(argv[++ind]);
					break;


				case 'z':
					addition_string = string(argv[++ind]);
					break;
				
				case 'l':
					frame_filter_rate = atoi(argv[++ind]);
					break;
				case 'n':
					learning_rate = atof(argv[++ind]);
					break;
				case 'm':
					iter_times = atoi(argv[++ind]);
					break;
				case 'd':
					cooling_rate = atof(argv[++ind]);
					break;
				case 'g':
					SAVE_IMG = true;
					break;
				case 'h':
					SAVE_LIKELI = true;
					break;

				default : printf("Unknown switch '%c'\n", argv[ind][1]);
				break;
			}
		}
	}

	init();
}